import React, {useState} from 'react';
import {
  Avatar,
  Backdrop,
  Card,
  CardHeader,
  Checkbox,
  CircularProgress,
  Divider,
  Fab,
  FormControlLabel,
  Tooltip
} from "@material-ui/core";
import Typography from "@material-ui/core/Typography";
import {color, toFirstLetter} from "../../../../../../assets/functions/functions";
import Grid from "@material-ui/core/Grid";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faExclamationTriangle} from "@fortawesome/free-solid-svg-icons";
import SnackbarMessage from "../../../Common/Snackbar/SnackbarMessage";
import {useDispatch} from "react-redux";
import {createNewIndicatorRequest, selectDeselectIndicator} from "../../../../../../redux/reducers/gqiEditor";
import CardContent from "@material-ui/core/CardContent";
import Collapse from "@material-ui/core/Collapse";
import {indicatorResponseToQueryWrapper, populateIndicatorQueryData} from "../../../../../../ruleEngine/rulesGenerator";
import parse from "html-react-parser";
import PreviewViz from "./components/PreviewViz";
import Backend from "../../../../../Backend/Backend";
import IndicatorDescription from "./components/IndicatorDescription";
import {getIndicatorDataForEdit} from "../../../../../../redux/reducers/editor";
import {useHistory} from "react-router-dom";
import {withStyles} from "@material-ui/core/styles";
import {green} from "@material-ui/core/colors";
import Button from "@material-ui/core/Button";
import EditIcon from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';
import CodeIcon from '@material-ui/icons/Code';
import IconButton from "@material-ui/core/IconButton";
import clsx from "clsx";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";

const GreenCheckbox = withStyles({
  root: {
    color: green[400],
    '&$checked': {
      color: green[600],
    },
  },
  checked: {},
})((props) => <Checkbox color="default" {...props} />);


export default function IndicatorCard(props) {
  // Props
  const {
    indicator,                // Particular indicator data
    classes,                  // Styles
    selectable,               // Property to make the card selectable to select {true : false}
    editable,                 // Property to make the card editable {true : false}
    selectedIndicators,       // List of all selected indicators (to compare)
    directedFromQuestionCard,
    responseData
  } = props;
  const {createdBy, name, indicatorType} = indicator;

  // Local constants
  const dispatch = useDispatch();
  let history = useHistory();
  const [expanded, setExpanded] = useState(false);
  const [openUndo, setOpenUndo] = useState(false);
  const [openViz, setOpenViz] = useState(false);
  const [copyLink, setCopyLink] = useState(false);
  const [loading, setLoading] = useState(false);
  const [infoMessage, setInfoMessage] = useState({
    message: "",
    type: "",
    error: false
  })
  const [visualizationDisplay, setVisualizationDisplay] = useState(false);
  const [scriptCodeData, setScriptCodeData] = useState(false);
  const [indicatorDescription, setIndicatorDescription] = useState({
    analysisMethod: "",
    analysisMethodParams: {},
    visualizationLibrary: "",
    visualizationType: "",
  })
  const [state, setState] = React.useState({
    checkedG: selectedIndicators.some(ind => ind.id === indicator.id),
  });


  const handleRequestIndicatorDetails = async () => {
    if (!expanded && !visualizationDisplay && !scriptCodeData) {
      generateDescription(indicator);
      setOpenViz(!openViz);
      setInfoMessage({
        ...infoMessage,
        message: "Visualization is loading!",
        type: "info",
        error: false
      });
      const vizQuery = indicatorResponseToQueryWrapper(indicator);
      await Backend.post("/AnalyticsEngine/GetIndicatorPreview", vizQuery)
        .then(response => {
          const unescapedVizCode = decodeURIComponent(response.data.visualizationCode);
          let objectData = parse(unescapedVizCode);
          let scriptData = objectData[1].props.dangerouslySetInnerHTML.__html;
          setScriptCodeData(scriptData);
          setVisualizationDisplay(parse(unescapedVizCode));
          setInfoMessage({
            ...infoMessage,
            message: "Visualization loaded!",
            type: "success",
            error: false
          });
        }, (error) => {
          console.log(error);
          setInfoMessage({
            ...infoMessage,
            message: "Error loading visualization",
            type: "error",
            error: true,
          });
        })
    }
    setExpanded(!expanded);
  }

  const generateDescription = async (indicator) => {
    if (indicator.indicatorType === "Basic Indicator") {
      let indicatorData = populateIndicatorQueryData(indicator);
      let analysisName = "";
      let library = "";
      let libraryType = "";
      await Backend.get(`/AnalyticsMethod/AnalyticsMethods/${indicatorData.analysisMethod.id}`).then(response => {
        analysisName = response.data.name;
      }, (error) => {
        console.log(error)
      })
      await Backend.get(`/AnalyticsEngine/GetVisualizations`)
        .then(response => {
          response.data.forEach(vizData => {
            if (vizData.id === indicatorData.vizMethodType.libraryId) {
              library = vizData.name;
              const {visualizationTypes} = vizData;
              visualizationTypes.forEach(type => {
                if (type.id === indicatorData.vizMethodType.typeId)
                  libraryType = type.name;
              })
            }
          })
          setIndicatorDescription({
            ...indicatorDescription,
            analysisMethod: analysisName,
            analysisMethodParams: indicatorData.analysisMethod.additionalParams,
            visualizationLibrary: library,
            visualizationType: libraryType,
          })
        }, (error) => {
          console.log(error)
        })
    }
  }

  const handleSelectIndicatorCard = (event) => {
    if (!selectedIndicators.some(ind => ind.id === indicator.id)) {
      setOpenUndo(true);
      setInfoMessage({
        ...infoMessage,
        message: "Indicator added to selection!",
        type: "success"
      });
    } else {
      setOpenUndo(true);
      setInfoMessage({
        ...infoMessage,
        message: "Indicator removed from selection!",
        type: "info"
      });
    }
    setState({...state, [event.target.name]: event.target.checked});
    dispatch(selectDeselectIndicator(indicator));
  }

  const handleCopyIndicatorLink = () => {
    if (responseData) {
      let {indicatorRequestCode} = responseData;
      navigator.clipboard.writeText(indicatorRequestCode);
      setCopyLink(!copyLink);
    }
  }

  const handleEditIndicator = async (indicator) => {
    setLoading(true);
    dispatch(getIndicatorDataForEdit(indicator));
    dispatch(createNewIndicatorRequest(indicator.indicatorType));
    setTimeout(() => {
      history.push("/basic");
    }, 2000)
  }

  return (
    <>
      <Grid container alignItems="center">
        {!directedFromQuestionCard && selectable ? (
          <Grid item>
            <FormControlLabel
              control={<GreenCheckbox checked={selectedIndicators.some(ind => ind.id === indicator.id)}
                                      onChange={handleSelectIndicatorCard}
                                      name="checkedG"/>}
            />
          </Grid>) : <></>}
        <Grid item xs>
          <Card raised
                className={selectable ?
                  selectedIndicators.some(ind => ind.id === indicator.id) ? classes.selectedBorder : ""
                  : ""}>
            <Grid container direction="row" alignItems="center">
              <Grid item xs>
                {selectable ? (
                  <CardHeader
                    avatar={<Avatar style={{backgroundColor: color(indicatorType), color: "#fff"}}>
                      {toFirstLetter(indicatorType)} </Avatar>}
                    title={<Grid container direction="column">
                      <Typography variant="overline">{indicatorType}</Typography>
                      <Typography variant="h6">{name}</Typography> </Grid>}
                    subheader={<Typography variant="overline">Author: {createdBy}</Typography>}
                  />
                ) : (
                  <CardHeader
                    avatar={<Avatar style={{backgroundColor: color(indicatorType), color: "#fff"}}>
                      {toFirstLetter(indicatorType)} </Avatar>}
                    title={<Grid container direction="column">
                      <Typography variant="overline">{indicatorType}</Typography>
                      <Typography variant="h6">{name}</Typography> </Grid>}
                    subheader={<Typography variant="overline">Author: {createdBy}</Typography>}
                  />
                )}
              </Grid>
              <Grid item>
                <Grid container alignItems="center">
                  {!directedFromQuestionCard && !selectable && selectedIndicators.some(ind => ind.id === indicator.id) ? (
                    <>
                      <Button size="small" startIcon={<DeleteIcon/>}
                              color="secondary" className={classes.gutterLeftRightLarge}
                              onClick={handleSelectIndicatorCard}>
                        Delete
                      </Button>

                      {editable ? (
                        <Button size="small" startIcon={<EditIcon/>} color="primary"
                                onClick={() => handleEditIndicator(indicator)}>
                          Edit
                        </Button>
                      ) : <></>}
                    </>
                  ) : <></>}
                  <Grid item>
                    <Grid container>
                      {responseData ? (
                        <Tooltip arrow title={<Typography>Copy HTML Embed Code</Typography>}>
                          <Fab size="small" onClick={handleCopyIndicatorLink}
                               className={classes.gutterLeftRightLarge}
                               color="primary">
                            <CodeIcon fontSize="small"/>
                          </Fab>
                        </Tooltip>
                      ) : <></>}
                      <Grid item className={classes.gutterLeftRightLarge}>
                        <Tooltip title={!expanded ? <Typography >Show Visualization</Typography> :
                          <Typography >Hide Visualization</Typography>}>
                          <IconButton variant="contained" className={clsx(classes.expand, {
                            [classes.expandOpen]: expanded,
                          })} onClick={handleRequestIndicatorDetails}>
                            <ExpandMoreIcon fontSize="large"/>
                          </IconButton>
                        </Tooltip>
                      </Grid>
                    </Grid>
                  </Grid>
                </Grid>
              </Grid>
            </Grid>
            <Collapse in={expanded} timeout="auto" unmountOnExit>
              <Divider/>
              <CardContent style={{backgroundColor: "#fff"}}>
                <Grid container spacing={3}>
                  {!infoMessage.error ? (
                    <>
                      <Grid item xs className={classes.gutterTop}>
                        {!visualizationDisplay && !scriptCodeData ? (
                          <Grid container direction="column" alignItems="center">
                            <CircularProgress className={classes.gutterTopBottom}/>
                            <Typography variant="overline" style={{color: "#000"}}>Loading Visualization</Typography>
                          </Grid>
                        ) : (
                          <PreviewViz scriptCodeData={scriptCodeData}
                                      visualizationDisplay={visualizationDisplay}/>
                        )}
                      </Grid>
                      <Grid item xs className={classes.gutterTopBottom}>
                        <Grid container justify="space-between" alignItems="flex-end" className={classes.gutterBottom}>
                          <Grid item>
                            <Typography variant="h6" style={{color: "#000"}}>Indicator Details:</Typography>
                          </Grid>
                        </Grid>
                        <Grid container direction="column">
                          <IndicatorDescription
                            classes={classes}
                            indicatorDescription={indicatorDescription}
                          />
                        </Grid>
                      </Grid>
                    </>
                  ) : (
                    <Grid container direction="column" justify="center" alignItems="center">
                      <FontAwesomeIcon icon={faExclamationTriangle} size={"4x"} color="red"
                                       className={classes.gutterTopBottom}/>
                      <Typography variant="h5" style={{color: "#000"}} gutterBottom>
                        Error loading details, please retry.
                      </Typography>
                    </Grid>
                  )}
                </Grid>

              </CardContent>
            </Collapse>
          </Card>
        </Grid>
      </Grid>


      <SnackbarMessage
        message={<Typography component={'span'}>{infoMessage.message}</Typography>}
        type={infoMessage.type}
        openSnackbar={openUndo}
        setOpenSnackbar={setOpenUndo}
        duration={3000}
        buttonAction={handleSelectIndicatorCard}
        buttonMessage={"undo"}
      />

      <SnackbarMessage
        message={<Typography component={'span'}>{infoMessage.message}</Typography>}
        type={infoMessage.type}
        openSnackbar={openViz}
        setOpenSnackbar={setOpenViz}
        duration={5000}
      />
      <SnackbarMessage
        message={<Typography component={'span'}>Embed code copied!</Typography>}
        type={"success"}
        openSnackbar={copyLink}
        setOpenSnackbar={setCopyLink}
        duration={5000}
        buttonAction={() => history.push('/demo')}
        buttonMessage={"Test your code here"}
      />
      <Backdrop className={classes.backdrop} open={loading}>
        <Grid container direction="column" justify="center" alignItems="center">
          <Grid item>
            <CircularProgress color="inherit"/>
          </Grid>
          <Grid item>
            <Typography>Loading Indicator data</Typography>
          </Grid>
        </Grid>
      </Backdrop>
    </>
  )
}
